frametimings: reuse previous frame timing in common case
authorChristian Hergert <chergert@redhat.com>
Tue, 26 Apr 2016 10:08:11 +0000 (03:08 -0700)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 26 Apr 2016 13:06:07 +0000 (09:06 -0400)
Typically, there won't be any references on old frame timings except for
the most recent timing. So instead of discarding these and re-entering
gslice twice, just steal the old frame timing and reuse it.

https://bugzilla.gnome.org/show_bug.cgi?id=765592

gdk/gdkframeclock.c
gdk/gdkframeclockprivate.h
gdk/gdkframetimings.c

index f84aee77bb06e436886a1e13bb923fe0888431bc..6f6d1a1d422f30e8eee05f728a658a053d410fe8 100644 (file)
@@ -416,12 +416,18 @@ _gdk_frame_clock_begin_frame (GdkFrameClock *frame_clock)
   priv->frame_counter++;
   priv->current = (priv->current + 1) % FRAME_HISTORY_MAX_LENGTH;
 
+  /* Try to steal the previous frame timing instead of discarding
+   * and allocating a new one.
+   */
+  if G_LIKELY (priv->n_timings == FRAME_HISTORY_MAX_LENGTH &&
+               _gdk_frame_timings_steal (priv->timings[priv->current],
+                                         priv->frame_counter))
+    return;
+
   if (priv->n_timings < FRAME_HISTORY_MAX_LENGTH)
     priv->n_timings++;
   else
-    {
-      gdk_frame_timings_unref(priv->timings[priv->current]);
-    }
+    gdk_frame_timings_unref(priv->timings[priv->current]);
 
   priv->timings[priv->current] = _gdk_frame_timings_new (priv->frame_counter);
 }
index cda5aff37b5a63f2d280ecc6b72ddd3612d50dfc..17e06dfcf765396f10d9e51fc071b5bb832e6370 100644 (file)
@@ -111,7 +111,9 @@ void _gdk_frame_clock_begin_frame         (GdkFrameClock   *clock);
 void _gdk_frame_clock_debug_print_timings (GdkFrameClock   *clock,
                                            GdkFrameTimings *timings);
 
-GdkFrameTimings *_gdk_frame_timings_new (gint64 frame_counter);
+GdkFrameTimings *_gdk_frame_timings_new   (gint64           frame_counter);
+gboolean         _gdk_frame_timings_steal (GdkFrameTimings *timings,
+                                           gint64           frame_counter);
 
 void _gdk_frame_clock_emit_flush_events  (GdkFrameClock *frame_clock);
 void _gdk_frame_clock_emit_before_paint  (GdkFrameClock *frame_clock);
index 0245d469d25b154ea2455ccca3715d51bdcc6ac2..7b8a3dd88cf88f0c8c42c5a63190af12d75bf8f5 100644 (file)
@@ -17,6 +17,8 @@
 
 #include "config.h"
 
+#include <string.h>
+
 #include "gdkframeclockprivate.h"
 
 /**
@@ -48,6 +50,21 @@ _gdk_frame_timings_new (gint64 frame_counter)
   return timings;
 }
 
+gboolean
+_gdk_frame_timings_steal (GdkFrameTimings *timings,
+                          gint64           frame_counter)
+{
+  if (timings->ref_count == 1)
+    {
+      memset (timings, 0, sizeof *timings);
+      timings->ref_count = 1;
+      timings->frame_counter = frame_counter;
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
 /**
  * gdk_frame_timings_ref:
  * @timings: a #GdkFrameTimings